boost::any库是个很短小的类,它的主要作用是定义一个变量来存放任意类型的数据,我们首先来看下boost::any的使用方法。

boost::any最常见的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <list>
#include <boost/any.hpp>
typedef std::list<boost::any> list_any; // 类型定义
void fill_list(list_any& la) {
la.push_back(10); // 存放整数
la.push_back(std::string("glemontree")); // 存放字符串对象,不能是la.push_back("glemontree"),否则会被当做字符串数组
}
void show_list(list_any& la) {
list_any::iterator it;
boost::any anyone;
for (it = la.begin; it!= la.end(); ++it) {
anyone = *it;
// C++中,typeid用于返回指针或引用所指对象的实际类型,typeid是操作符,不是函数
if (anyone.type() == typeid(int)) {
std::cout << boost::any_cast<int>(*it) << std::endl;
} else if (anyone.type() == typeid(std::string)) {
// c_str()函数返回一个指向正规C字符串的指针,内容与本string相同
std::cout << boost::any_cast<std::string>(*it).c_str() << std::endl;
}
}
}

boost::any可以表示任意类型,因此list_any可以存放任意类型的对象,也正因为boost::any可以表示任意类型,因此用不了多态的特性,因为没有统一的接口,因此在show_list()函数中获取容器中的元素时需要判别元素的真正类型,这增加了程序员的负担。

boost::any源码

实现any的功能主要由三部分组成:

  • any类
  • 真正保存数据的holder类和其基类placeholder
  • 获取真正数据的模板函数any_cast,类型转换的功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <list>
#include <cassert>
class any {
public:
class placeholder {
public:
virtual ~placeholder() {
}
public:
virtual const std::type_info& type() const = 0;
virtual placeholder* clone() const = 0;
};
template<typename ValueType>
class holder : public placeholder {
public:
holder(const ValueType& value): held(value) {
}
public:
virtual const std::type_info& type() const {
return typeid(ValueType);
}
virtual placeholder* clone() const {
return new holder(held);
}
public:
ValueType held;
};
public:
any(): content(NULL) {
}
//模板构造函数,参数可以是任意类型,真正的数据保存在content中
template<typename ValueType>
any(const ValueType& value): content(new holder<ValueType>(value)) {
}
//拷贝构造函数
any(const any& other): content(other.content ? other.content->clone() : 0) {
}
~any() {
if (NULL != content) {
delete content;
}
}
private:
placeholder* content;
template<typename ValueType>
friend ValueType any_cast(const any* operand);
public:
const std::type_info& type() const {
return content ? content->type() : typeif(void);
}
};
template<typename ValueType>
ValueType any_cast(const any& operand) {
assert(operand.type() == typeid(ValueType));
return static_cast<any::holder<ValueType>*>(operand.content)->held;
}

参考资料